package com.qiyi.player.core.ad
{
   import com.qiyi.player.core.IDestroy;
   import com.qiyi.player.core.player.coreplayer.ICorePlayer;
   import flash.display.Sprite;
   import flash.utils.Timer;
   import com.qiyi.player.core.ad.file.AdFile;
   import com.qiyi.player.base.logging.ILogger;
   import flash.utils.ByteArray;
   import flash.geom.Rectangle;
   import com.qiyi.player.core.player.def.StatusEnum;
   import com.qiyi.player.core.player.events.PlayerEvent;
   import flash.events.TimerEvent;
   import flash.events.Event;
   import com.qiyi.player.core.video.file.actors.datatile.MediaData;
   import com.qiyi.player.base.logging.Log;
   
   public class AdEngine extends Object implements IDestroy
   {
      
      public function AdEngine(param1:Sprite, param2:ICorePlayer) {
         this._log = Log.getLogger("com.qiyi.player.core.ad.AdEngine");
         super();
         this._parent = param1;
         this._holder = param2;
         this._adProxys = new Vector.<AdPlayerProxy>();
         this._adProxys.push(new AdPlayerProxy(this._parent,this._holder));
         this._adProxys.push(new AdPlayerProxy(this._parent,this._holder));
         var _loc3_:* = 0;
         while(_loc3_ < this._adProxys.length)
         {
            this._adProxys[_loc3_].addEventListener(AdEvent.Evt_BufferEmpty,this.onBufferEmpty);
            this._adProxys[_loc3_].addEventListener(AdEvent.Evt_ADStatusChanged,this.onADStatusChanged);
            _loc3_++;
         }
         this._timer = new Timer(100);
         this._timer.addEventListener(TimerEvent.TIMER,this.onTimer);
         this._adFile = new AdFile();
         this._holder.addEventListener(PlayerEvent.Evt_StatusChanged,this.onPlayerStatusChanged);
      }
      
      private static const GRADIENT_VOLUME_DURATION:int = 3;
      
      private static const GRADIENT_LOW_VOLUME_DISCOUNT:Number = 0.2;
      
      private var _holder:ICorePlayer;
      
      private var _parent:Sprite;
      
      private var _adProxys:Vector.<AdPlayerProxy>;
      
      private var _timer:Timer;
      
      private var _adFile:AdFile;
      
      private var _playedAds:int;
      
      private var _frameCount:int;
      
      protected var _log:ILogger;
      
      public function get duration() : int {
         return this._adFile.getDuration(this._playedAds - 1) / 1000;
      }
      
      public function get currentTime() : int {
         var _loc1_:AdPlayerProxy = this.getADProxyByPlaying();
         if(_loc1_)
         {
            return _loc1_.time / 1000;
         }
         return 0;
      }
      
      public function inject(param1:String, param2:ByteArray, param3:Boolean, param4:Boolean) : void {
         this._adFile.inject(param1,param2,param3,param4);
      }
      
      public function getADArea() : Rectangle {
         return this._adProxys[0].getADArea();
      }
      
      public function setADRect(param1:int, param2:int, param3:int, param4:int) : void {
         var _loc5_:* = 0;
         while(_loc5_ < this._adProxys.length)
         {
            this._adProxys[_loc5_].setADRect(param1,param2,param3,param4);
            _loc5_++;
         }
      }
      
      public function setADVolume(param1:int) : void {
         var _loc2_:* = 0;
         while(_loc2_ < this._adProxys.length)
         {
            this._adProxys[_loc2_].setADVolume(param1);
            _loc2_++;
         }
      }
      
      public function playAd(param1:String) : void {
         this.pushData();
         if(!this._timer.running)
         {
            this._timer.start();
         }
         var _loc2_:AdPlayerProxy = this.getADProxyById(param1);
         if(_loc2_)
         {
            this._log.debug("[AdEngine.playAd]: played ads = " + this._playedAds + " currentIndexPlayed = " + _loc2_.adIndex + " id = " + param1);
            this._playedAds++;
            _loc2_.playAd();
            this._holder.removeStatus(StatusEnum.AD_END);
            this._holder.addStatus(StatusEnum.AD_ALREADYPLAY);
         }
         else
         {
            this._log.error("[AdEngine.playAd]: id = " + param1 + " dosen\'t exist.");
         }
      }
      
      public function pauseAd() : void {
         var _loc1_:AdPlayerProxy = this.getADProxyByPlaying();
         if(_loc1_)
         {
            _loc1_.pauseAd();
         }
      }
      
      public function stopAd(param1:String, param2:Boolean = false) : void {
         var _loc3_:AdPlayerProxy = this.getADProxyById(param1);
         if(_loc3_)
         {
            this._log.info("[AdEngine.stopAd]: currentTime = " + _loc3_.time + " duration = " + this._adFile.getDurationById(param1) + " id = " + param1);
         }
         if(param2)
         {
            this._log.info("[AdEngine.stopAd]: skip ad by user");
            this._timer.stop();
            this._adFile.skiped = true;
            this._adProxys[0].stopAd();
            this._adProxys[1].stopAd();
            this._holder.removeStatus(StatusEnum.AD_ALREADYPLAY);
            this._holder.addStatus(StatusEnum.AD_END);
            return;
         }
         if(this._playedAds == this._adFile.length - 1 && (this._adFile.checkIsLastAd(param1)))
         {
            return;
         }
         this._adFile.stopAdFlvById(param1);
         _loc3_ = this.getADProxyByPlaying();
         if((_loc3_) && _loc3_.adId == param1)
         {
            this._log.info("[AdEngine.stopAd]: stop middle ad by AdPlayer, id = " + param1);
            _loc3_.stopAd();
            this._holder.removeStatus(StatusEnum.AD_ALREADYPLAY);
            this._holder.addStatus(StatusEnum.AD_END);
         }
         else if(_loc3_)
         {
            this._log.error("[AdEngine.stopAd]: current playing Flv id " + _loc3_.adId + " is not equal: " + param1);
         }
         else
         {
            this._log.error("[AdEngine.stopAd]: there is no playing Flv, id = " + param1);
         }
         
         if(!this._timer.running)
         {
            this._timer.start();
         }
      }
      
      public function seekAd() : void {
      }
      
      public function resumeAd() : void {
         var _loc1_:AdPlayerProxy = this.getADProxyByPlaying();
         if(_loc1_)
         {
            _loc1_.resumeAd();
         }
      }
      
      public function clearAd(param1:String) : void {
         this._adFile.stopAdFlvById(param1);
         var _loc2_:AdPlayerProxy = this.getADProxyById(param1);
         if(_loc2_)
         {
            this._log.debug("[AdEngine.clearAd]: index = " + this._adFile.curReadAdIndex + " id = " + param1);
            _loc2_.reset();
         }
         else
         {
            this._log.error("[AdEngine.clearAd]: id = " + param1 + " doesn\'t exist.");
         }
      }
      
      public function removeAdLayer() : void {
         var _loc1_:AdPlayerProxy = this.getADProxyByPlaying();
         if(_loc1_)
         {
            this._log.debug("[AdEngine.removeAdLayer]: enter video play and removeAdLayer");
            _loc1_.stopAd();
            this._holder.removeStatus(StatusEnum.AD_ALREADYPLAY);
            this._holder.addStatus(StatusEnum.AD_END);
         }
         else
         {
            this._log.error("[AdEngine.removeAdLayer]: there is no playing AdFlv.");
         }
      }
      
      public function destroy() : void {
         var _loc1_:* = 0;
         while(_loc1_ < this._adProxys.length)
         {
            this._adProxys[_loc1_].removeEventListener(AdEvent.Evt_BufferEmpty,this.onBufferEmpty);
            this._adProxys[_loc1_].removeEventListener(AdEvent.Evt_ADStatusChanged,this.onADStatusChanged);
            this._adProxys[_loc1_].destroy();
            this._adProxys[_loc1_] = null;
            _loc1_++;
         }
         this._adProxys = null;
         this._adFile.reset();
         this._adFile = null;
         this._holder.removeEventListener(PlayerEvent.Evt_StatusChanged,this.onPlayerStatusChanged);
         this._holder = null;
         this._timer.stop();
         this._timer.removeEventListener(TimerEvent.TIMER,this.onTimer);
         this._timer = null;
         this._parent.removeEventListener(Event.ENTER_FRAME,this.onEnterFrame);
         this._parent = null;
      }
      
      private function reset() : void {
         this._log.info("[AdEngine.reset] reset status and member.");
         this._holder.removeStatus(StatusEnum.AD_ALREADYPLAY,false);
         this._holder.removeStatus(StatusEnum.AD_PLAYING,false);
         this._holder.removeStatus(StatusEnum.AD_PAUSED,false);
         this._holder.removeStatus(StatusEnum.AD_SEEKING,false);
         this._holder.removeStatus(StatusEnum.AD_WAITING,false);
         this._holder.removeStatus(StatusEnum.AD_END,false);
         this._parent.removeEventListener(Event.ENTER_FRAME,this.onEnterFrame);
         this._timer.stop();
         this._adProxys[0].reset();
         this._adProxys[1].reset();
         this._adFile.reset();
         this._playedAds = 0;
         this._frameCount = 0;
      }
      
      private function onPlayerStatusChanged(param1:PlayerEvent) : void {
         if(param1.data.isAdd as Boolean)
         {
            switch(param1.data.status)
            {
               case StatusEnum.ALREADY_LOAD_MOVIE:
                  this.reset();
                  break;
               case StatusEnum.ALREADY_READY:
                  this._timer.reset();
                  this._timer.start();
                  this._parent.addEventListener(Event.ENTER_FRAME,this.onEnterFrame);
                  break;
               case StatusEnum.ALREADY_PLAY:
                  this._adFile.reset();
                  this._timer.stop();
                  this._parent.removeEventListener(Event.ENTER_FRAME,this.onEnterFrame);
                  this._holder.removeStatus(StatusEnum.AD_ALREADYPLAY);
                  this._holder.removeStatus(StatusEnum.AD_PLAYING);
                  this._holder.removeStatus(StatusEnum.AD_PAUSED);
                  this._holder.removeStatus(StatusEnum.AD_SEEKING);
                  this._holder.removeStatus(StatusEnum.AD_WAITING);
                  this._holder.removeStatus(StatusEnum.AD_END);
                  break;
               case StatusEnum.PLAYING:
                  this._holder.removeStatus(StatusEnum.AD_END);
                  this._adProxys[0].reset();
                  this._adProxys[1].reset();
                  break;
               case StatusEnum.AD_END:
                  this._holder.removeStatus(StatusEnum.AD_PLAYING);
                  this._holder.removeStatus(StatusEnum.AD_PAUSED);
                  this._holder.removeStatus(StatusEnum.AD_SEEKING);
                  this._holder.removeStatus(StatusEnum.AD_WAITING);
                  break;
            }
         }
      }
      
      private function onTimer(param1:TimerEvent) : void {
         this.pushData();
      }
      
      private function pushData() : void {
         var _loc2_:MediaData = null;
         var _loc1_:AdPlayerProxy = this.getAvailableADPlayerProxy();
         if(_loc1_ == null)
         {
            this._timer.stop();
            return;
         }
         if(!this._adFile.empty && !this._adFile.exported && !this._adFile.skiped)
         {
            _loc2_ = new MediaData();
            if((this._adFile.header) && this._adFile.currentPos == this._adFile.header.length)
            {
               _loc2_.headers = this._adFile.header;
            }
            _loc2_.bytes = this._adFile.read();
            if(_loc2_.bytes)
            {
               if(_loc1_.adId != this._adFile.curReadAdId)
               {
                  this._log.info("[AdEngine.onTimer]: lastIndex = " + _loc1_.adIndex + "  currentIndex = " + this._adFile.curReadAdIndex + " id = " + this._adFile.curReadAdId);
                  _loc1_.updateDecoder();
                  _loc1_.adId = this._adFile.curReadAdId;
                  _loc1_.adIndex = this._adFile.curReadAdIndex;
                  _loc1_.isReading = true;
               }
               _loc1_.appendData(_loc2_);
               _loc1_.fillEnd = this._adFile.currentAdExported;
               _loc2_ = null;
               if(_loc1_.fillEnd)
               {
                  _loc1_.isReading = false;
                  this._adFile.curReadAdIndex++;
               }
            }
         }
      }
      
      private function onBufferEmpty(param1:AdEvent) : void {
         var _loc2_:AdPlayerProxy = this.getADProxyByPlaying();
         if((_loc2_) && (_loc2_.fillEnd))
         {
            this._holder.removeStatus(StatusEnum.AD_ALREADYPLAY);
            this._holder.addStatus(StatusEnum.AD_END);
            if(!this._timer.running)
            {
               this._timer.start();
            }
            this._log.debug("[AdEngine.onBufferEmpty]: middle flv ad play end, waiting to play next flv ad");
         }
      }
      
      private function onADStatusChanged(param1:AdEvent) : void {
         switch(param1.data)
         {
            case StatusEnum.AD_PLAYING:
               this._holder.removeStatus(StatusEnum.AD_PAUSED);
               this._holder.removeStatus(StatusEnum.AD_SEEKING);
               this._holder.removeStatus(StatusEnum.AD_WAITING);
               this._holder.removeStatus(StatusEnum.AD_END);
               this._log.info("engine ADstatus changed: playing");
               break;
            case StatusEnum.AD_PAUSED:
               this._holder.removeStatus(StatusEnum.AD_PLAYING);
               this._holder.removeStatus(StatusEnum.AD_SEEKING);
               this._holder.removeStatus(StatusEnum.AD_WAITING);
               this._holder.removeStatus(StatusEnum.AD_END);
               this._log.info("engine ADstatus changed: paused");
               break;
            case StatusEnum.AD_SEEKING:
               this._log.info("engine ADstatus changed: seeking");
               break;
            case StatusEnum.AD_WAITING:
               this._log.info("engine ADstatus changed: waiting");
               break;
         }
         this._holder.addStatus(param1.data as int);
      }
      
      private function onEnterFrame(param1:Event) : void {
         var _loc2_:AdPlayerProxy = null;
         var _loc3_:* = 0;
         var _loc4_:* = 0;
         var _loc5_:* = NaN;
         this._frameCount++;
         if(this._frameCount % 5 == 0)
         {
            this._frameCount = 0;
            _loc2_ = this.getADProxyByPlaying();
            if((_loc2_) && this._adFile.getDurationById(_loc2_.adId) - _loc2_.time < 3000)
            {
               _loc2_.setEndSequence();
            }
            if((this._holder.hasStatus(StatusEnum.AD_PLAYING) && this._adFile.exported && this._playedAds == this._adFile.length - 1 && _loc2_) && (this._adFile.checkIsLastAd(_loc2_.adId)) && _loc2_.volume > 0)
            {
               _loc3_ = Math.min(this.duration,GRADIENT_VOLUME_DURATION);
               _loc4_ = _loc2_.time / 1000;
               if(this.duration - _loc4_ <= _loc3_)
               {
                  _loc5_ = this._adProxys[0].volume * GRADIENT_LOW_VOLUME_DISCOUNT + _loc2_.volume * (1 - GRADIENT_LOW_VOLUME_DISCOUNT) * (this.duration - _loc4_) / _loc3_;
                  _loc2_.smoothVolume(_loc5_);
               }
            }
         }
      }
      
      private function getADProxyById(param1:String) : AdPlayerProxy {
         var _loc2_:* = 0;
         while(_loc2_ < this._adProxys.length)
         {
            if(this._adProxys[_loc2_].adId == param1 && !(param1 == ""))
            {
               return this._adProxys[_loc2_];
            }
            _loc2_++;
         }
         return null;
      }
      
      private function getADProxyByPlaying() : AdPlayerProxy {
         var _loc1_:* = 0;
         while(_loc1_ < this._adProxys.length)
         {
            if(this._adProxys[_loc1_].isPlaying)
            {
               return this._adProxys[_loc1_];
            }
            _loc1_++;
         }
         return null;
      }
      
      private function getAvailableADPlayerProxy() : AdPlayerProxy {
         var _loc1_:* = 0;
         _loc1_ = 0;
         while(_loc1_ < this._adProxys.length)
         {
            if((this._adProxys[_loc1_].isReading) && !this._adProxys[_loc1_].fillEnd)
            {
               return this._adProxys[_loc1_];
            }
            _loc1_++;
         }
         _loc1_ = 0;
         while(_loc1_ < this._adProxys.length)
         {
            if(!this._adProxys[_loc1_].fillEnd)
            {
               return this._adProxys[_loc1_];
            }
            _loc1_++;
         }
         return null;
      }
   }
}
